Vancouver, unlike other major cities that boast iconic skylines, is renowned for its natural beauty. The city is a tapestry of beaches, neighborhood areas lush with greenery, and towering mountains that frame its skyline. Among its most celebrated features are the majestic trees that line the streets and the stunning cherry blossoms that adorn neighborhoods every spring.
As a photography enthusiast, I've often marveled at the captivating images of Vancouver's cherry blossoms shared online. However, I've also encountered the challenge of pinpointing the best locations to capture these scenes myself. This project is driven by my passion for both the natural beauty of Vancouver and photography, aiming to analyze the distribution of street trees and cherry blossoms across the city.
This project will be using a subset of the Vancouver Street Trees dataset with 5,000 rows. We will be using the Vancouver city geojson using a URL from Vancouver Data Portal for geographical visualizations with Altair.
import altair as alt
import pandas as pd
import os
import json
#alt.data_transformers.enable('data_server')
The Vancouver Street trees dataset is said to include "a listing of public trees on boulevards in the City of Vancouver and provides data on tree coordinates, species and other related characteristics. Park trees and private trees are not included in the inventory. Data currency: The dataset refreshes daily on weekdays. Tree attributes are updated on a regular basis but it may be several years between updates for some attributes. Priorities and resources determine how fast a change in reality is reflected in the data."
A description for columns in the dataset that is needed for explanation.
Some columns are self-explanatory from its column name (e.g. neighbourhood_name is for neighbourhood name):
| Column | Description |
|---|---|
| ON_STREET | The name of the street at which the tree is physically located on |
| SPECIES_NAME | species name |
| NEIGHBOURHOOD_NAME | neighbourhood name |
| DATE_PLANTED | Date is in YYYY-MM-DD format. Planted date of new trees is added after every planting season, usually at the beginning of January and June. Note: Data for this field may not be available for all trees. |
| DIAMETER | DBH in inches (DBH stands for diameter of tree at breast height) |
| GENUS_NAME | genus name |
| COMMON_NAME | common name |
| HEIGHT_RANGE_ID | 0-10 for every 10 feet (e.g., 0 = 0-10 ft, 1 = 10-20 ft, 2 = 20-30 ft, and 10 = 100+ ft) |
| ROOT_BARRIER | Root barrier installed (Y = Yes, N = No) |
Before going into the data analysis and visualization, let's filter the dataframe with only the columns that will be used.
Here's a snapshot of how the dataset currently looks like:
vancity_trees = pd.read_csv('small_unique_vancouver__20240624182849.csv')
vancity_trees.info()
vancity_trees.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5000 entries, 0 to 4999 Data columns (total 21 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Unnamed: 0 5000 non-null int64 1 std_street 5000 non-null object 2 on_street 5000 non-null object 3 species_name 5000 non-null object 4 neighbourhood_name 5000 non-null object 5 date_planted 2363 non-null object 6 diameter 5000 non-null float64 7 street_side_name 5000 non-null object 8 genus_name 5000 non-null object 9 assigned 5000 non-null object 10 civic_number 5000 non-null int64 11 plant_area 4950 non-null object 12 curb 5000 non-null object 13 tree_id 5000 non-null int64 14 common_name 5000 non-null object 15 height_range_id 5000 non-null int64 16 on_street_block 5000 non-null int64 17 cultivar_name 2658 non-null object 18 root_barrier 5000 non-null object 19 latitude 5000 non-null float64 20 longitude 5000 non-null float64 dtypes: float64(3), int64(5), object(13) memory usage: 820.4+ KB
| Unnamed: 0 | std_street | on_street | species_name | neighbourhood_name | date_planted | diameter | street_side_name | genus_name | assigned | ... | plant_area | curb | tree_id | common_name | height_range_id | on_street_block | cultivar_name | root_barrier | latitude | longitude | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 10747 | W 20TH AV | W 20TH AV | PLATANOIDES | Riley Park | 2000-02-23 | 28.5 | EVEN | ACER | N | ... | 15 | Y | 21421 | NORWAY MAPLE | 4 | 0 | NaN | N | 49.252711 | -123.106323 |
| 1 | 12573 | W 18TH AV | W 18TH AV | CALLERYANA | Arbutus-Ridge | 1992-02-04 | 6.0 | ODD | PYRUS | N | ... | 7 | Y | 129645 | CHANTICLEER PEAR | 2 | 2300 | CHANTICLEER | N | 49.256350 | -123.158709 |
| 2 | 29676 | ROSS ST | ROSS ST | NIGRA | Sunset | NaN | 12.0 | ODD | PINUS | N | ... | 7 | Y | 154675 | AUSTRIAN PINE | 4 | 7800 | NaN | N | 49.213486 | -123.083254 |
| 3 | 8856 | DOMAN ST | DOMAN ST | AMERICANA | Killarney | 1999-11-12 | 11.0 | EVEN | FRAXINUS | N | ... | 7 | Y | 180803 | AUTUMN APPLAUSE ASH | 4 | 6900 | AUTUMN APPLAUSE | N | 49.220839 | -123.036721 |
| 4 | 21098 | EAST BOULEVARD | EAST BOULEVARD | HIPPOCASTANUM | Shaughnessy | NaN | 15.5 | ODD | AESCULUS | Y | ... | N | Y | 74364 | COMMON HORSECHESTNUT | 4 | 5200 | NaN | N | 49.238514 | -123.154958 |
5 rows × 21 columns
This observation sees 5000 data entries, 21 total columns consisting of 8 numerical columns (float64 and int64). We're seeing some columns doesn't have 5000 entries indicating there are null values. Let's observe how many null values there are.
# Note: analysis on latitude and longitude aren't useful.
trees_df = vancity_trees[[
"on_street",
"species_name",
"neighbourhood_name",
"date_planted",
"diameter",
"genus_name",
"common_name",
"height_range_id",
"root_barrier",
"latitude",
"longitude"
]]
trees_df
trees_df.describe()
| diameter | height_range_id | latitude | longitude | |
|---|---|---|---|---|
| count | 5000.000000 | 5000.00000 | 5000.000000 | 5000.000000 |
| mean | 12.340888 | 2.73440 | 49.247349 | -123.107128 |
| std | 9.266600 | 1.56957 | 0.021251 | 0.049137 |
| min | 0.000000 | 0.00000 | 49.202783 | -123.220560 |
| 25% | 4.000000 | 2.00000 | 49.230152 | -123.144178 |
| 50% | 10.000000 | 2.00000 | 49.247981 | -123.105861 |
| 75% | 18.000000 | 4.00000 | 49.263275 | -123.063484 |
| max | 71.000000 | 9.00000 | 49.293930 | -123.023311 |
trees_df.describe(exclude='number', datetime_is_numeric=True)
| on_street | species_name | neighbourhood_name | date_planted | genus_name | common_name | root_barrier | |
|---|---|---|---|---|---|---|---|
| count | 5000 | 5000 | 5000 | 2363 | 5000 | 5000 | 5000 |
| unique | 607 | 171 | 22 | 1599 | 67 | 361 | 2 |
| top | CAMBIE ST | SERRULATA | Renfrew-Collingwood | 2004-02-16 | ACER | KWANZAN FLOWERING CHERRY | N |
| freq | 49 | 463 | 384 | 7 | 1218 | 383 | 4679 |
A skeleton map of Vancouver will be generated first before we map the data and label the neighbourhoods.
trees_geojson = url_geojson = 'https://raw.githubusercontent.com/UBC-MDS/exploratory-data-viz/main/data/local-area-boundary.geojson'
data_geojson = alt.Data(url=trees_geojson, format=alt.DataFormat(property='features',type='json'))
data_geojson
Data({
format: DataFormat({
property: 'features',
type: 'json'
}),
url: 'https://raw.githubusercontent.com/UBC-MDS/exploratory-data-viz/main/data/local-area-boundary.geojson'
})
vancouver_map_outline = alt.Chart(data_geojson).mark_geoshape(
color = 'lightblue',
opacity= 0.5,
stroke='black').encode(
).project(type='identity', reflectY=True)
vancouver_map_outline
scatter_plot = alt.Chart(vancity_trees).mark_circle(
size=60,
opacity=0.5
).encode(
x=alt.X('longitude:Q', title='Longitude', scale=alt.Scale(zero=False)),
y=alt.Y('latitude:Q', title='Latitude', scale=alt.Scale(zero=False)),
color=alt.Color(
'diameter:Q',
title='Tree Diameter',
scale=alt.Scale(scheme='greens') # Apply green color scheme
),
tooltip=['species_name', 'neighbourhood_name', 'diameter']
).properties(
width=550,
height=400,
title='Scatter Plot of Trees in Vancouver by Longitude and Latitude'
)
vancouver_map_outline + scatter_plot
This scatter plot shows the location of all the trees. However, this graph doesn't give us much useful information at first glance.
count_df = trees_df.groupby('neighbourhood_name')['neighbourhood_name'].count().reset_index(name='tree_count')
points_df = trees_df.groupby('neighbourhood_name')['longitude','latitude'].median()#.reset_index()
counts_df = count_df.merge(points_df, on ='neighbourhood_name')
<ipython-input-8-a4812a868b61>:2: FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead.
points_df = trees_df.groupby('neighbourhood_name')['longitude','latitude'].median()#.reset_index()
van_circle_size = (
alt.Chart(counts_df).mark_circle().encode(
longitude='longitude',
latitude='latitude',
size='tree_count:Q',
color=alt.Color('tree_count:Q', title='Tree count'),
tooltip=['name:N', alt.Tooltip('tree_count:Q', title='Tree counts')],
)
.project(type='identity', reflectY=True)
.properties(height=200, width=400, title='Vancouver neighbourhoods')
)
van_map_points = vancouver_map_outline + van_circle_size
van_map_points
This visualization is informative as the size and shade of the circle is readable, but there is a much better way to communicate this data.
click = alt.selection_single(fields=['neighbourhood_name'])
title = alt.TitleParams(
'Figure 1. Vancouver tree counts and Cherry Blossom distribution',
subtitle='Renfrew-Collingwood has the most trees. Hover over neighbourhoods to see its total amount of trees',
)
vancouver_map = (
alt.Chart(data_geojson)
.mark_geoshape()
.transform_lookup(
lookup='properties.name',
from_=alt.LookupData(counts_df, 'neighbourhood_name', ['tree_count', 'neighbourhood_name']),
)
.encode(
color=alt.Color('tree_count:Q', title=' Tree count'),
tooltip=['neighbourhood_name:N', alt.Tooltip('tree_count:Q', title='Tree counts')],
)
.add_selection(click)
.project(type='identity', reflectY=True)
.properties(title=title, height=400, width=700,)
)
vancouver_map
The choropleth map is a much better method to convey this type of information for area density. At a glance, we can quickly distinguish the area with dense trees by the shade of the colour.
Now, before graphing the cherry trees data points, we need to filter and defines the ones we want to display. I'm choosing to visualize the top 6 most popular cherry trees in Vancouver.
cherry_trees = trees_df[trees_df['common_name'].str.contains('CHERRY')]
# Vancouver top 6 most populary cherry trees
cherry_trees_6 = (
cherry_trees.groupby('common_name')['common_name']
.count()
.reset_index(name='count')
.sort_values(by='count', ascending=False).iloc[:6,0].tolist()
)
cherry_trees = cherry_trees[cherry_trees['common_name'].isin(cherry_trees_6)]
cherry_trees
| on_street | species_name | neighbourhood_name | date_planted | diameter | genus_name | common_name | height_range_id | root_barrier | latitude | longitude | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 21 | E 49TH AV | SERRULATA | Sunset | NaN | 14.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 3 | N | 49.225494 | -123.087200 |
| 42 | W 35TH AV | SERRULATA | Shaughnessy | NaN | 11.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.239992 | -123.152677 |
| 44 | VERNON DRIVE | SERRULATA | Strathcona | NaN | 22.0 | PRUNUS | UKON JAPANESE CHERRY | 3 | N | 49.277064 | -123.079379 |
| 60 | CAMOSUN ST | SERRULATA | Dunbar-Southlands | NaN | 16.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.246430 | -123.196900 |
| 62 | CAROLINA ST | SERRULATA | Mount Pleasant | NaN | 12.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.261203 | -123.091148 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 4978 | DUMFRIES ST | SERRULATA | Victoria-Fraserview | NaN | 24.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 3 | N | 49.220258 | -123.074637 |
| 4988 | W 16TH AV | SERRULATA | Shaughnessy | NaN | 7.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 1 | N | 49.257003 | -123.130106 |
| 4989 | E 35TH AV | SERRULATA | Kensington-Cedar Cottage | NaN | 27.0 | PRUNUS | UKON JAPANESE CHERRY | 4 | N | 49.238311 | -123.087098 |
| 4992 | E 53RD AV | SERRULATA | Victoria-Fraserview | NaN | 20.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.221161 | -123.060833 |
| 4995 | E 53RD AV | SERRULATA | Victoria-Fraserview | NaN | 17.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.221161 | -123.061023 |
541 rows × 11 columns
Now we add the neighbourhoods label and include the cherry tree points on click.
# Add Labels Layer
labels = (
alt.Chart(counts_df)
.mark_text()
.encode(
longitude='longitude',
latitude='latitude',
text='neighbourhood_name:N',
size=alt.value(10),
opacity=alt.value(1),
)
.project(type='identity', reflectY=True)
.properties(height=400, width=700, title='Vancouver map')
)
# Cherry tree points layer
cherry_trees_layer = (
alt.Chart(cherry_trees)
.mark_circle(size=30, color='pink', opacity=0.9)
.encode(
longitude='longitude:Q',
latitude='latitude:Q',
color=alt.Color('common_name:N', title='Cherry tree types', scale=alt.Scale(
range=['#ffdede', '#FF69B4', '#882238', '#D1C4E9', '#616c99', '#505477']
), legend=None),
tooltip=['common_name:N', 'neighbourhood_name:N', 'date_planted:N']
)
.transform_filter(click) # Filter points based on selected neighbourhood
.project(type='identity', reflectY=True)
)
vancouver_map = vancouver_map + cherry_trees_layer + labels
vancouver_map
This map looks good with points coloured to resemble the different types of cherry trees.
import pandas as pd
import plotly.express as px
# Load the data
df = pd.read_csv('small_unique_vancouver__20240624182849.csv', sep=',')
# Getting neighborhood totals
df2 = pd.merge(
df[['neighbourhood_name']].value_counts().reset_index().rename(columns={'neighbourhood_name': 'NEIGHBOURHOOD_NAME', 0: 'count'}),
df[['neighbourhood_name', 'longitude', 'latitude']].groupby('neighbourhood_name').mean().reset_index().rename(columns={'neighbourhood_name': 'NEIGHBOURHOOD_NAME'})
)
# Drawing the figure
fig = px.scatter_mapbox(
df2,
lat='latitude',
lon='longitude',
color='count',
opacity=0.5,
center=dict(lon=df2['longitude'].mean(), lat=df2['latitude'].mean()),
zoom=10,
size_max=15
)
fig.update_layout(
mapbox_style='open-street-map',
width=600,
height=400
)
fig
Although this visualization method above hasn't been taught in this course, this implementation could be further explored for a future project. I will need to figure out how to accurately plot the Vancouver neighbourhoods boundary points to overlay onto this detailed map of Vancouver. For the sake of saving time and the aim for minimalistic visualization, I will continue with the choropleth map.
The choropleth map of Vancouver's neighborhoods shows the number of trees in each area. The map is colored according to tree count, with a colour gradient ranging from light yellow (fewer trees) to dark blue (more trees). From the map, we can see that Renfrew-Collingwood neighbourhood is highlighted as having the highest number of trees at 384 counts. The two neighbourhoods besides Renfrew-Collingwood comes close at second place for Kensington-Cedar Cottage with 375 trees and third place for Hastings-Sunrise with 340 trees. The Strathacona neighbourhood has the least amount of tree with a count of 75.
I want to have an interative bar graph with the vancouver map of the most common trees for each neighbourhoods on click. By default, it shows the most common trees for Vancouver city (all neighbourhoods combined).
# Hold shift to select multiple neighbourhoods
click = alt.selection_multi(fields=['neighbourhood_name'])
vancouver_map_interactive = vancouver_map.encode(
opacity=alt.condition(click, alt.value(1), alt.value(0.3))
).add_selection(click)
# slider bar to control the number of trees to display
slider = alt.binding_range(
name='Number of popular trees to display: ',
step=1,
min=5,
max=20)
select_trees = alt.selection_single(
fields=['num_names'], init={'num_names': 20}, bind = slider)
# Bar Chart
title = alt.TitleParams(
'Figure 2. Most popular trees in selected neighbourhoods',
subtitle='Kwanzan Flowering Cherry is the most popular tree in Vancouver',
)
common_tree_names = (
alt.Chart(trees_df).transform_filter(click).mark_bar().encode(
x=alt.X('count:Q', title=''),
y=alt.Y('common_name:N', title='', sort='-x'),
color=alt.value('#4A993A')
)
.transform_aggregate(count='count()', groupby=['common_name'])
.transform_window(
rank='rank(count)', sort=[alt.SortField('count', order='descending')]
)
.transform_filter(alt.datum.rank <= select_trees.num_names)
.properties(title=title, height=400, width=300)
.add_selection(click)
.add_selection(select_trees)
)
vancouver_map_interactive | common_tree_names
From this graph, we can see the top 5 Vancouver's most common trees are Kawanzan Flowering Cherry, Pissard Plum, Norway Maple, Crimean Linden, and the Pryamidal European Hornbeam. It is interesting to see that the Vancouver West Side neighbourhoods doesn't even have Pryamidal European Hornbeam ranked in the top 20. Vancouver West Side has American Elm ranked 4th most popular and Crimean Linden ranked 5th most popular.
The Kwanzan Flowering Cherry has been consistently the top 3 most common trees for Vancouver neighbourhoods.
This is the most exciting part of the Vancouver tree analysis! How are the beautiful cherry blossom tress distributed across Vancouver city? I will visualize this using bar chart interacting with the Vancouver map on click.
# The most popular cherry trees
cherry_trees_6 = (
cherry_trees.groupby('common_name')['common_name']
.count()
.reset_index(name='count')
.sort_values(by='count', ascending=False).iloc[:6,0].tolist()
)
cherry_trees = cherry_trees[cherry_trees['common_name'].isin(cherry_trees_6)]
cherry_trees
| on_street | species_name | neighbourhood_name | date_planted | diameter | genus_name | common_name | height_range_id | root_barrier | latitude | longitude | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 21 | E 49TH AV | SERRULATA | Sunset | NaN | 14.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 3 | N | 49.225494 | -123.087200 |
| 42 | W 35TH AV | SERRULATA | Shaughnessy | NaN | 11.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.239992 | -123.152677 |
| 44 | VERNON DRIVE | SERRULATA | Strathcona | NaN | 22.0 | PRUNUS | UKON JAPANESE CHERRY | 3 | N | 49.277064 | -123.079379 |
| 60 | CAMOSUN ST | SERRULATA | Dunbar-Southlands | NaN | 16.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.246430 | -123.196900 |
| 62 | CAROLINA ST | SERRULATA | Mount Pleasant | NaN | 12.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.261203 | -123.091148 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 4978 | DUMFRIES ST | SERRULATA | Victoria-Fraserview | NaN | 24.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 3 | N | 49.220258 | -123.074637 |
| 4988 | W 16TH AV | SERRULATA | Shaughnessy | NaN | 7.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 1 | N | 49.257003 | -123.130106 |
| 4989 | E 35TH AV | SERRULATA | Kensington-Cedar Cottage | NaN | 27.0 | PRUNUS | UKON JAPANESE CHERRY | 4 | N | 49.238311 | -123.087098 |
| 4992 | E 53RD AV | SERRULATA | Victoria-Fraserview | NaN | 20.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.221161 | -123.060833 |
| 4995 | E 53RD AV | SERRULATA | Victoria-Fraserview | NaN | 17.0 | PRUNUS | KWANZAN FLOWERING CHERRY | 2 | N | 49.221161 | -123.061023 |
541 rows × 11 columns
title = alt.TitleParams(
'Figure 3. Cherry trees in selected neighbourhoods',
subtitle=['Renfrew-Collingwood has the most number of cherry trees','downtown vancouver has the least (clickable)'],
)
neighbourhood_cherry_trees = (
alt.Chart(cherry_trees, title=title).mark_bar().encode(
alt.X('count()'),
alt.Y('neighbourhood_name:N', sort=alt.SortField(field='neighbourhood_name', order='ascending'), title=''),
color=alt.Color('common_name:N', title='Cherry tree types', scale=alt.Scale(
range=['#ffdede', '#FF69B4', '#882238', '#D1C4E9', '#616c99', '#505477']
), legend=alt.Legend(title='Cherry Tree Types', orient='right')),
opacity=alt.condition(click, alt.value(1), alt.value(0.3)),
)
.add_selection(click)
.properties(height=400, width=300)
)
(vancouver_map_interactive | neighbourhood_cherry_trees)
During springtime in Vancouver, the neighbourhood with the most cherry blossoms are Renfrew Collingwood, Mount Pleasant, and Dunbar-Southlands.
Arbutus-Ridge and Downtown only has 2 varieties of cherry blossoms, whereas in Grandview-Woodland and Mount Pleasant you will find a great variety of cherry blossom.
We have two numerical data columns in our dataset; tree height and diameter. We will use the top 25 most common trees to answer this question. A scatterplot will be graphed with a visualization on the mean diameter line and a dropdown menu to view the "heigh and diameter" relationship of different trees.
top_trees = (
trees_df['common_name']
.value_counts()[:20]
.sort_values(ascending=False)
.reset_index(name='count')
)
tree_names = sorted(top_trees['index'].unique())
dropdown_menu = alt.binding_select(
name='Select tree type to view its height and diameter relationship: ',
options=tree_names,
)
select_tree = alt.selection_single(fields=['common_name'], bind=dropdown_menu)
# Graphing the scatter plot
tree_scatter_plot = (alt.Chart(trees_df).mark_circle().encode(alt.X('diameter', title='Diameter (inch)'), alt.Y('height_range_id'))
).transform_filter(select_tree)
plot_line_title = alt.TitleParams(
'Figure 4. Height and diameter relationship of popular Vancouver trees',
subtitle=['The line indicating the mean diameter over height ranges.'],
)
tree_line_plot = (
alt.Chart(trees_df, title=plot_line_title).mark_line(color='hotPink').encode(
alt.X('mean(diameter)'),
alt.Y('height_range_id', title='Height range ID'),
tooltip=alt.value('Mean of diameter'),
).properties(height = 200, width = 800)
).transform_filter(select_tree)
tree_size = tree_line_plot + tree_scatter_plot
##
vancouver_map_interactive |(tree_line_plot + tree_scatter_plot).add_selection(click)
tree_size = tree_size.add_selection( click).add_selection(click).add_selection(select_tree).transform_filter(select_tree)
tree_size
The default view shows the data points of all the top 20 common Vancouver trees. We can see there is a general positive relationship between tree height and diameter. For all the tree species, we can also see a general positive relationship betwen tree height and diameter. Due to the lack of data for the tallest tree of each species, sometimes the data trend skews to a negative correlation at the higher "height range ID."
The trees of Vancouver not only provides the city with a beautiful scene, but it has a functional purpose to boost health and wellness such as clean air, provide shading, and creates shelter for wild animals. This data analysis provides a detailed exploration of the distribution and charatersitcs of Vancouver's street trees with a focus on cherry blossoms.
The map highlights the Renfrew-Collingwood neighborhood as having the highest number of trees, with a total count of 384. Kensington-Cedar Cottage and Hastings-Sunrise follow closely, with 375 and 340 trees. In contrast, the Strathcona neighborhood has the least number of trees, with only 75 counted. This distribution suggests a significant variation in tree density across Vancouver, with certain neighborhoods having a much higher concentration of trees.
Vancouver's top 5 most common trees are the Kwanzan Flowering Cherry, Pissard Plum, Norway Maple, Crimean Linden, and Pyramidal European Hornbeam. Using the multi-selection tool for multiple neighbourhoods, it is noteworthy to point out that the Vancouver West Side neighborhoods (borders from the west of Mount Pleasant, Riley Park, and Sunset) do not even rank the Pyramidal European Hornbeam in their top 20 most common trees. Instead, these neighborhoods have the American Elm as the 4th most popular and the Crimean Linden as the 5th most popular tree. This observation highlights the regional variations in tree popularity within Vancouver.
The Kwanzan Flowering Cherry consistently ranks among the top 3 most common trees in Vancouver neighborhoods. This consistency showcases the tree's popularity and its significance in the Vancouver urban landscape in the spring season. During springtime, the neighborhoods with the most cherry blossoms are Renfrew-Collingwood, Mount Pleasant, and Dunbar-Southlands. The variety of cherry blossoms is also notable, with Grandview-Woodland and Mount Pleasant offering a wide range of cherry blossom species. In contrast, Arbutus-Ridge and Downtown only feature 2 varieties, which may reflect different urban planting strategies. Different cherry blossom species have different blossoming times and duration. It would be interesting to do analysis to see if cherry blossom blooming time have a relationship to planting stragegies.
In conclusion, this analysis of Vancouver street trees reveals insights into the distribution and characteristics to the city's urban forest planning. The data shows a widespread of cherry blossom trees particularly in neighborhoods like Renfrew-Collingwood, Mount Pleasant, and Dunbar-Southlands, which are rich in variety and tree density.
The observation of tree species popularity between different areas, such as the distinct preferences in Vancouver's West Side neighborhoods, suggest that urban planning and community preferences play a crucial role in shaping the city's tree canopy.
The relationship between tree height and diameter observed in the scatter plot suggests potential avenues for future research, including exploring whether taller trees (as a potential indicator of older neighbourhoods) are more common in wealthier neighborhoods. Future projects could also involve a deeper investigation into the socioeconomic factors influencing tree distribution in Vancouver. Additionally, exploring the environmental and aesthetic impact of tree types in urban areas could provide valuable insights for city planning and conservation efforts.
This analysis not only sheds light on Vancouver's current state of tree distribution, it also lays a foundation for future urban forest planning aimed to enhance the city's natual beauty and sustainability.
alt.themes.enable('none');
(
vancouver_map_interactive.properties(width = 750)
& (common_tree_names | neighbourhood_cherry_trees).add_selection(click)
& tree_size.add_selection(select_tree).transform_filter(select_tree))
# .configure_view(stroke=None)
Data Source:
Vancouver Street trees by the City of Vancouver
Article that sparked interest:
CBC - Why Metro Vancouver's cherry blossom trees offer more than just a pretty picture